pg_atropos
Snip your dumps into manageable threads
Split PostgreSQL custom-format dumps into individual files — each table, function, index, and role in its own file. Clean diffs, clear history, no more merge conflicts.
# Split a dump into individual files
$ pg_atropos -f dump.pgdump -o ./structure
# From local database
$ pg_dump -Fc mydb | pg_atropos -f - -o ./structure
# From remote server via connection string
$ pg_dump -Fc postgresql://user@host:5432/db | pg_atropos -f - -o ./structure
✓ Extracted 24 objects to ./structure▌
What is pg_atropos?
pg_atropos is a Go command-line tool that splits PostgreSQL pg_dump -Fc (custom-format) dumps into individual files organized for Git versioning. Instead of wrestling with a single giant SQL file, each database object gets its own file — tables in TABLE/, functions in FUNCTION/, roles in ROLE/, and so on.
Rather than parsing raw SQL text with brittle regex, it pipes through pg_restore -f - which reliably emits clean -- Name: ...; Type: ... headers. The result: simpler, faster, and far more robust parsing.
Why split your dump?
Minimal conflicts
Two people can change different tables without stepping on each other. No more "merge conflict in 500-line SQL file."
Clear code review
A diff shows exactly the changed object, not 500 lines of dump header. Review becomes a pleasure.
Readable history
git log -- TABLE/users.sql shows every change to that specific table. Full audit trail per object.
CI/CD friendly
Deploy only the changed object, not the entire dump. Faster pipelines, less risk.
Installation
Homebrew (recommended)
The easiest way to install on macOS and Linux.
$ brew install heptau/tap/pg-atropos
From source
Requires Go 1.23+.
$ git clone https://github.com/heptau/pg_atropos.git
$ cd pg_atropos && make build
* Requires pg_restore (from PostgreSQL client tools) in your PATH.
Usage & Flags
pg_atropos works from a dump file, a live database, or stdin pipe. Here are all supported flags:
| Flag | Default | Description |
|---|---|---|
--db | "" | Database name to dump |
--conn | "" | PostgreSQL connection string |
--file, -f | "" | Custom-format dump file ("-" for stdin) |
--output, -o | ./output | Output directory |
--mode, -m | origin | Output mode: origin | custom |
--clean | false | Clean output directory before processing |
--no-db-path | false | Don't include database name in output path |
--blacklist-db | ^(template|postgres) | Skip databases matching pattern |
--whitelist-db | "" | Only include databases matching pattern |
--exclude-obj | "" | Exclude object types matching pattern |
--acl-files | false | Save ACLs to separate .acl.sql files |
--move-roles | false | Move role files under database directory |
--dry-run | false | Print what would be extracted without writing |
--quiet | false | Suppress informational output |
--version | — | Print version and exit |
Examples
# From a custom-format dump file
$ pg_atropos -f dump.pgdump -o ./structure
# From a live database (auto-dump via pg_dump)
$ pg_atropos -d mydb -o ./structure
# Pipe from remote database via connection string
$ pg_dump -Fc postgresql://user@host:5432/db | pg_atropos -f - -o ./structure
# Custom mode (lowercase directories for CI)
$ pg_atropos -f dump.pgdump -o ./structure -m custom
Modes
origin (default)
Mirrors the dump structure exactly — each object type gets its own directory (TABLE/, FUNCTION/, INDEX/, …). Ideal for inspection and manual browsing.
custom
Lowercase directories (table/, function/, …). Better suited for CI / automation workflows. Note: INDEX/CONSTRAINT/TRIGGER merging into table files is not supported (pg_restore headers lack parent table name).
The Name
In Greek mythology, the three Moirai (Fates) spun the thread of life, measured it, and — finally — Atropos (the Inevitable) cut it with her shears. pg_atropos does the same: it takes a giant pg_dump file and snips it into small, manageable threads (files) ready for Git.
Performance
Tested on ~150 objects / 2226 lines of SQL output:
| Version | Avg Time | vs pg_atropos |
|---|---|---|
| pg_atropos (Go) | 0.044s | 1× |
| pgdump_splitter (Go) | 0.109s | 2.5× slower |